﻿using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Kooboo.Commerce;

using System.IO;
using System.Linq;
using Kooboo.Commerce.AddIn;
using Kooboo.IoC;

namespace Kooboo.Web.Areas.Commerce.Binders
{
    public class ProductTypeBinder : EntityBinder
    {
        protected override string[] SkipProperties
        {
            get
            {
                return new string[] { "CustomFields", "Variations" };
            }
        }
        protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
        {
            var model = ObjectContainer.CreateInstance<IProductType>();

            var form = controllerContext.HttpContext.Request.Form;

            #region CustomFields
            model.CustomFields = new List<ICustomField>();


            var customFieldsIndexes = form["CustomFields.index"];

            if (customFieldsIndexes != null)
            {
                foreach (var i in customFieldsIndexes.Split(','))
                {
                    var prefix = "CustomFields[" + i + "]";
                    var field = ObjectContainer.CreateInstance<ICustomField>();
                    field.Id = int.Parse(form[prefix + ".Id"]);
                    field.Name = form[prefix + ".Name"];
                    field.Sequence = int.Parse(form[prefix + ".Sequence"]);
                    field.Selections = new List<string>();
                    using (StringReader reader = new StringReader(form[prefix + ".Selections"]))
                    {
                        var item = reader.ReadLine();
                        while (item != null)
                        {
                            field.Selections.Add(item);
                            item = reader.ReadLine();
                        }
                    }

                    field.DefaultValues = form[prefix + ".DefaultValues"];

                    var webControlName = form[prefix + ".WebControl.Name"];
                    if (string.IsNullOrWhiteSpace(webControlName) == false)
                    {
                        field.WebControl = ObjectContainer.CreateInstances<IWebControl>()
                            .Where(n => n.Name == webControlName)
                            .FirstOrDefault();

                    }

                    field.DataFormat = (DataFormat)(int.Parse(form[prefix + ".DataFormat"]));

                    field.ValidationRules = new List<IValidationRule>();

                    var ruleIndexes = form[prefix + ".ValidationRules.index"];
                    if (ruleIndexes != null)
                    {
                        foreach (var ruleIndex in ruleIndexes.Split(','))
                        {
                            var rule_prefix = prefix + ".ValidationRules[" + ruleIndex + "]";
                            var rule = ObjectContainer.CreateInstance<IValidationRule>();
                            rule.Id = int.Parse(form[rule_prefix + ".Id"]);
                            rule.ErrorMessage = form[rule_prefix + ".ErrorMessage"];
                            var validatorName = form[rule_prefix + ".Validator.Name"];
                            if (string.IsNullOrWhiteSpace(validatorName) == false)
                            {
                                rule.Validator = ObjectContainer.CreateInstances<IValidator>()
                                    .Where(n => n.Name == validatorName)
                                    .FirstOrDefault();
                            }

                            rule.Parameters = new List<ValidatorParameter>();

                            var paraIndexes = form[rule_prefix + ".Parameters.index"];
                            if (string.IsNullOrWhiteSpace(paraIndexes) == false)
                            {
                                foreach (var paraIndex in paraIndexes.Split(','))
                                {
                                    var para_prefix = rule_prefix + ".Parameters[" + paraIndex + "]";

                                    var para = new ValidatorParameter();
                                    para.Name = form[para_prefix + ".Name"];
                                    para.Value = form[para_prefix + ".Value"];
                                    //para.Example = form[para_prefix + ".Example"];

                                    rule.Parameters.Add(para);
                                }
                            }

                            field.ValidationRules.Add(rule);

                        }
                    }

                    model.CustomFields.Add(field);
                }
            } 
            #endregion

            #region Variations
            model.Variations = new List<IVariation>();


            var variationIndexes = form["Variations.index"];


            if (string.IsNullOrWhiteSpace(variationIndexes) == false)
            {
                foreach (var i in variationIndexes.Split(','))
                {
                    var prefix = "Variations[" + i + "]";
                    var variation = ObjectContainer.CreateInstance<IVariation>();
                    variation.Id = int.Parse(form[prefix + ".Id"]);
                    variation.Name = form[prefix + ".Name"];
                    variation.Sequence = int.Parse(form[prefix + ".Sequence"]);
                    variation.Selections = new List<string>();
                    using (StringReader reader = new StringReader(form[prefix + ".Selections"]))
                    {
                        var item = reader.ReadLine();
                        while (item != null)
                        {
                            variation.Selections.Add(item);
                            item = reader.ReadLine();
                        }
                    }

                    variation.DefaultValues = form[prefix + ".DefaultValues"];

                    var webControlName = form[prefix + ".WebControl.Name"];
                    if (string.IsNullOrWhiteSpace(webControlName) == false)
                    {
                        variation.WebControl = ObjectContainer.CreateInstances<IWebControl>()
                            .Where(n => n.Name == webControlName)
                            .FirstOrDefault();

                    }

                    variation.DataFormat = (DataFormat)(int.Parse(form[prefix + ".DataFormat"]));

                    variation.ValidationRules = new List<IValidationRule>();

                    var ruleIndexes = form[prefix + ".ValidationRules.index"];
                    if (ruleIndexes != null)
                    {
                        foreach (var ruleIndex in ruleIndexes.Split(','))
                        {
                            var rule_prefix = prefix + ".ValidationRules[" + ruleIndex + "]";
                            var rule = ObjectContainer.CreateInstance<IValidationRule>();
                            rule.Id = int.Parse(form[rule_prefix + ".Id"]);
                            rule.ErrorMessage = form[rule_prefix + ".ErrorMessage"];
                            var validatorName = form[rule_prefix + ".Validator.Name"];
                            if (string.IsNullOrWhiteSpace(validatorName) == false)
                            {
                                rule.Validator = ObjectContainer.CreateInstances<IValidator>()
                                    .Where(n => n.Name == validatorName)
                                    .FirstOrDefault();
                            }

                            rule.Parameters = new List<ValidatorParameter>();

                            var paraIndexes = form[rule_prefix + ".Parameters.index"];
                            if (string.IsNullOrWhiteSpace(paraIndexes) == false)
                            {
                                foreach (var paraIndex in paraIndexes.Split(','))
                                {
                                    var para_prefix = rule_prefix + ".Parameters[" + paraIndex + "]";

                                    var para = new ValidatorParameter();
                                    para.Name = form[para_prefix + ".Name"];
                                    para.Value = form[para_prefix + ".Value"];
                                    //para.Example = form[para_prefix + ".Example"];

                                    rule.Parameters.Add(para);
                                }
                            }

                            variation.ValidationRules.Add(rule);

                        }
                    }

                    model.Variations.Add(variation);
                }
            } 
            #endregion

            return model;
        }
    }
}